package qj.ps;

import static qj.util.SwingUtil.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.sql.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import javax.swing.*;

import qj.tool.build.BuildUtil;
import qj.ui.DesktopUI4;
import qj.util.*;
import qj.util.appCommon.swing.AppFrame;
import qj.util.funct.*;
import qj.util.math.Range;
import qj.util.swing.SwingLists;
import qj.util.swing.SwingLists.ListItem;

@SuppressWarnings("unchecked")
public class AssemblerUI {
	static String configFilePath = "data/config/assembler_ui.properties";
	
	static List<P0> onConfigUpdateds = new LinkedList<P0>();
	
	static Properties config;
	static {
		P0 loadConfigF = new P0() {public void e() {
			config = PropertiesUtil.loadPropertiesFromFile(configFilePath);
			Fs.invokeAll(onConfigUpdateds);
		}};
		FileUtil.onChange(configFilePath, loadConfigF);
		loadConfigF.e();
	}
	
	static P0 deployF = null;

	static F0<String> dummyIfDirF = new F0<String>() {public String e() {
		return config.getProperty("dummyIfDir");
	}};
	static F0<String> assemDirF = new F0<String>() {public String e() {
		return config.getProperty("assemDir");
	}};
	static F0<String> projectHomeF = new F0<String>() {public String e() {
		return config.getProperty("projectHome");
	}};
	static F0<String> ifHomeF = new F0<String>() {public String e() {
		return config.getProperty("ifHome");
	}};
	
	static F0<String> appserverF = new F0<String>() {public String e() {
		return new File(projectHomeF.e() + "/appserver").listFiles()[0].getPath();
	}};
	static F0<String> ifAppserverF = StringUtil.concat(ifHomeF, "/appserver/er_if-domain");
	
	static {
		
		
		deployF = new P0() {public void e() {
			deployClasses("ER_INTEGRATION_core");
			
			// jUnit tests
//			deployClasses("ER_api_CR_1978");
//			
//			deployClasses("ER_subscriptions_CR_1978");
//			deployClasses("APPLICATION_centralconfig_CR_1978");
//			deployClasses("APPLICATION_app_common_CR_1978");
//			deployClasses("ER_transactions_log_CR_1978");

//			deployClasses("ECOM_PLUGIN_log4j");
//			deployClasses("ECOM_MESSAGING_CR_1978");
//			deployClasses("ER_transactions_CR_1978");
//			deployClasses("APPLICATION_er_decoupling_CR_1978");
//			deployClasses("ER_CORE_api_CR_1978");
//			deployClasses("ER_transactions_log_CR_1978");
//			deployClasses("ER_rating_CR_1978");
//			deployClasses("ER_delegate_CR_1978");
			
//			deployClasses("ER_NFOR_logging");
//			
//			FileUtil.copyFile(new File(projectHomeF.e() + "/working/CONFIG_APPSERVER_er_core_batch_CR_1978/resources/startup/token/jboss/conf/log4j.xml.multi_tenancy"), 
//					new File(appserverF.e() + "/environment/token/jboss/conf/log4j.xml"));
			
//			ZipUtil.update(new File(appserverF.e() + "/applications/ercore.ear/APP-INF/lib/httpclient-4.0.1.jar"),
//					new File(projectHomeF.e() + "/working/ER_api_CR_1978/bin/"), toClassFilePaths(Arrays.asList("org.apache.http.impl.client.DefaultHttpClient"))
//					);
		}};
	}
//	public static void main(String[] args) {
//		DesktopUtil.openText(assemDirF.e() + "/country.properties");
//	}

	
	public static void main(String[] args) {
		final AppFrame frame = new AppFrame("Assembler " + new File(projectHomeF.e()).getName());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Container cp = frame.getContentPane();
		JButton deployBtn = new JButton("Deploy");
		final JLabel jbossStatus = new JLabel("                   ");
		cp.add(SwingUtil.panel_border(
				SwingUtil.panel_horizontal(
						deployBtn
				)
				, jbossStatus)
				);
		deployBtn.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
			deployF.e();
			frame.setStatus("Class file is deployed");
		}});

		menu(frame);
		
		P0 checkJbossStatus = new P0() {public void e() {
			File pidFile = new File(appserverF.e() + "/engine.pid");
			if (pidFile.exists()) {
				jbossStatus.setText("     Jboss is running   ");
				jbossStatus.setBackground(Color.green);
			} else {
				jbossStatus.setText("     Jboss is NOT running");
				jbossStatus.setBackground(Color.red);
			}
			jbossStatus.repaint();
		}};
		SwingUtil.onFocus(frame, checkJbossStatus);
		
		onConfigUpdateds.add(new P0() {public void e() {
			frame.setStatus("Config updated");
		}});
		
		SwingUtil.show(frame);
	}

	protected static void deployClasses(String project) {
		ZipUtil.zip(
				new File(projectHomeF.e() + "/working/" + project + "/bin"), 
				new File(new File(appserverF.e() + "/applications").listFiles()[0].getPath() + "/APP-INF/lib/" + project + ".jar"));		
	}

	protected static Collection<String> toClassFilePaths(Collection<String> classNames) {
		return Cols.yield(classNames, new F1<String,String>() {public String e(String className) {
			return className.replaceAll("\\.", "/") + ".class";
		}});
	}

	private static void menu(final AppFrame frame) {

		JMenu jbossMenu = frame.getMenu("JBoss");
		jbossItems(frame, jbossMenu);
		
		JMenu junitMenu = frame.getMenu("JUnit");
		junitItems(junitMenu, frame);

		JMenu dbMenu = frame.getMenu("DB");
		dbItems(frame, dbMenu);

		JMenu fileMenu = frame.getMenu("File");
		fileItems(fileMenu, frame);
		
		JMenu assemMenu = frame.getMenu("Assem");
		assemItems(frame, assemMenu);
		

		JMenu logMenu = frame.getMenu("Log");
		logItems(logMenu, frame);
		
		JMenu toolMenu = frame.getMenu("Tool");
		toolItems(toolMenu, frame);
		
		JMenu ifMenu = frame.getMenu("If");
		ifItems(ifMenu,frame);
		
	}

	private static void logItems(JMenu logMenu, final AppFrame frame) {
		logMenu.add(SwingUtil.menuItem("Tail decoupling.log", new P0() {public void e() {
			showTail(appserverF.e() + "/logs/decoupling.log", frame);
		}}));
		logMenu.add(SwingUtil.menuItem("Trace log files", ThreadUtil.async(new P0() {public void e() {
			List<File> logFiles = getLogFiles();
			
			
			LinkedList<Douce<File, Long>> status = new LinkedList<Douce<File, Long>>();
			for (File file : logFiles) {
				status.add(new Douce<File, Long>(file, file.length()));
			}
			
			System.out.println("Waiting to trace file...");
			SystemUtil.readLine();
			System.out.println("Showing trace.");
			
			LinkedList<ListItem> items = new LinkedList<SwingLists.ListItem>();
			
			for (Douce<File, Long> douce : status) {
				final File file = douce.get1();
				final Long oldLength = douce.get2();
				if (file.length()!=oldLength) {
//					System.out.println(file.getName());
					
					items.add(new ListItem(file.getName(), new P0() {public void e() {
						DesktopUI4.alert2(FileUtil.readFilePortionToString(file, oldLength));
					}}));
				}
			}
			DesktopUI4.alert(SwingLists.createList(items));
//			System.out.println("Tracing done");
		}})));
	}
	private static void toolItems(JMenu toolMenu, final AppFrame frame) {
		toolMenu.add(SwingUtil.menuItem("Open config file", new P0() {public void e() {
			DesktopUtil.openText(configFilePath);
		}}));
	}

	private static void jbossItems(final AppFrame frame, JMenu jbossMenu) {
		final P0 fixConfigDbPropertiesFile = new P0() {public void e() {
			FileUtil.replaceContent(appserverF.e() + "/applications/ercore.ear/config.db.properties", new F1<String,String>() {public String e(String obj) {
				return obj.replace("=environment/token", "=" + appserverF.e() + "/environment/token");
			}});
		}};
		
		jbossMenu.add(SwingUtil.menuItem("Start JBoss", new P0() {public void e() {
			// Remove trash files
//			/home/quanle/Workon/assembler/manifest-work/sla/dev/er_core_batch_12-1-BETA_03012012/appserver/er-core-batch-domain/jboss/deploy/er-ds.xml
//			FileUtil.deleteChilds(appserverF.e() + "/jboss/deploy", new F1<File,Boolean>() {public Boolean e(File obj) {
//				return obj.getName().startsWith("er-ds.xml.");
//			}});
			
			ProcessBuilder pb = new ProcessBuilder(ProcessUtil.shell("jbctl -c start -a core", appserverF.e()).split(" "));
//			pb.
			pb.directory(new File(appserverF.e()));
			pb.environment().put("JAVA_OPTIONS", "-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000");
			Process jbossProcess;
			try {
				jbossProcess = pb.start();
			} catch (IOException e1) {
				throw new RuntimeException(e1);
			}
			
//			Process jbossProcess = ProcessUtil.exec("jbctl -c start -a core", appserverF.e());
			ProcessUtil.showConsole("JBoss", jbossProcess, frame);
			ProcessUtil.onExit(jbossProcess, fixConfigDbPropertiesFile);
		}}));
		jbossMenu.add(SwingUtil.menuItem("Tail nohup.out", new P0() {public void e() {
			showTail(appserverF.e() + "/nohup.out", frame);
		}}));
		jbossMenu.add(SwingUtil.menuItem("Show nohup.out", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/nohup.out");
		}}));
		
		jbossMenu.add(SwingUtil.menuItem("Kill JBoss", new P0() {public void e() {
			File pidFile = new File(appserverF.e() + "/engine.pid");
			if (pidFile.exists()) {
				String processId = StringUtil.firstLine(FileUtil
						.readFileToString(pidFile));
				ProcessUtil.exec("kill -9 " + processId);
				frame.setStatus("JBoss process " + processId + " is killed");
				pidFile.delete();
			} else {
				frame.setStatus("JBoss pid file is not found");
			}
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/env.properties", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/environment/token/env.properties");
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/config.db.properties", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/environment/token/config.db.properties");
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/ercore.ear/META-INF/application.xml", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/environment/token/ercore.ear/META-INF/application.xml");
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/ercore.ear/META-INF/persistence.xml", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/environment/token/ercore.ear/META-INF/persistence.xml");
		}}));
		
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/jbctl", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/jbctl");
		}}));
		
		jbossMenu.add(SwingUtil.menuItem("Fix build", new P0() {public void e() {
			FileUtil.replaceContent(appserverF.e() + "/jbctl", Fs.sequel(
					StringUtil.replaceF("APPLICATION_app_common.jar", "APPLICATION_app_common*.jar"),
					StringUtil.replaceF("APPLICATION_centralconfig.jar", "APPLICATION_centralconfig*.jar")
					));
			FileUtil.replaceContent(appserverF.e() + "/environment/token/ercore.ear/META-INF/application.xml", StringUtil.replaceF("ER_delegate.jar", "ER_delegate_CR_1978.jar"));
			FileUtil.replaceContent(appserverF.e() + "/environment/token/env.properties", Fs.sequel(
					RegexUtil.replaceAllF("datadirectory=\\S+", "datadirectory=" + appserverF.e() + "/applications/ercore.ear"),
					RegexUtil.replaceAllF("er.server.host=\\S+", "er.server.host=localhost"),
					StringUtil.assureLineF("translog.logfilepath.mode=" + appserverF.e() + "/logs/translog_GB.log")
					));
			FileUtil.moveReplace(new File(appserverF.e() + "/environment/token/jboss/conf/log4j.xml.multi_tenancy"), 
					new File(appserverF.e() + "/environment/token/jboss/conf/log4j.xml")
					);
			useExampleZip(frame, "catalog_GB");
			useExampleZip(frame, "catalog_DE");
			useExampleZip(frame, "promocodes_GB");
			useExampleZip(frame, "promocodes_DE");
			new File(appserverF.e() + "/logs").mkdirs();
			
			FileUtil.replaceContent(appserverF.e() + "/environment/token/env_GB.properties", Fs.sequel(
					StringUtil.replaceF("translog.logging.mode=false", "translog.logging.mode=true"),
					StringUtil.assureLineF("translog.logfilepath.mode=" + appserverF.e() + "/logs/translog_GB.log")
					));
			FileUtil.replaceContent(appserverF.e() + "/environment/token/env_DE.properties", Fs.sequel(
					StringUtil.replaceF("translog.logging.mode=false", "translog.logging.mode=true"),
					StringUtil.assureLineF("translog.logfilepath.mode=" + appserverF.e() + "/logs/translog_DE.log")
					));
			
			frame.setStatus("Fix build done.");
		}}));
	}

	private static void ifItems(JMenu jbossMenu, final AppFrame frame) {
		
		jbossMenu.add(SwingUtil.menuItem("Start JBoss", new P0() {public void e() {
			
			ProcessBuilder pb = new ProcessBuilder(ProcessUtil.shell("jbctl -c start -oAA", ifAppserverF.e()).split(" "));
			pb.directory(new File(ifAppserverF.e()));
			//pb.environment().put("JAVA_OPTIONS", "-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000");
			Process jbossProcess;
			try {
				jbossProcess = pb.start();
			} catch (IOException e1) {
				throw new RuntimeException(e1);
			}
			
//			Process jbossProcess = ProcessUtil.exec("jbctl -c start -a core", appserverF.e());
			ProcessUtil.showConsole("JBoss", jbossProcess, frame);
		}}));
		jbossMenu.add(SwingUtil.menuItem("Tail nohup.out", new P0() {public void e() {
			showTail(ifAppserverF.e() + "/nohup.out", frame);
		}}));
		jbossMenu.add(SwingUtil.menuItem("Show nohup.out", new P0() {public void e() {
			DesktopUtil.openText(ifAppserverF.e() + "/nohup.out");
		}}));
		
		jbossMenu.add(SwingUtil.menuItem("Kill JBoss", new P0() {public void e() {
			File pidFile = new File(ifAppserverF.e() + "/engine.pid");
			if (pidFile.exists()) {
				String processId = StringUtil.firstLine(FileUtil
						.readFileToString(pidFile));
				ProcessUtil.exec("kill -9 " + processId);
				frame.setStatus("JBoss process " + processId + " is killed");
				pidFile.delete();
			} else {
				frame.setStatus("JBoss pid file is not found");
			}
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/env.properties", new P0() {public void e() {
			DesktopUtil.openText(ifAppserverF.e() + "/environment/token/env.properties");
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/config.db.properties", new P0() {public void e() {
			DesktopUtil.openText(ifAppserverF.e() + "/environment/token/config.db.properties");
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/ercore.ear/META-INF/application.xml", new P0() {public void e() {
			DesktopUtil.openText(ifAppserverF.e() + "/environment/token/ercore.ear/META-INF/application.xml");
		}}));
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/environment/token/ercore.ear/META-INF/persistence.xml", new P0() {public void e() {
			DesktopUtil.openText(ifAppserverF.e() + "/environment/token/ercore.ear/META-INF/persistence.xml");
		}}));
		
		jbossMenu.add(SwingUtil.menuItem("$APPSERVER/jbctl", new P0() {public void e() {
			DesktopUtil.openText(ifAppserverF.e() + "/jbctl");
		}}));
		
	}

	private static void junitItems(JMenu junitMenu, final AppFrame frame) {
		junitMenu.add(SwingUtil.menuItem("Show junit.out", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/scripts/junit.out");
		}}));
		junitMenu.add(SwingUtil.menuItem("Show junit.sh", new P0() {public void e() {
			DesktopUtil.openText(appserverF.e() + "/scripts/junit.sh");
		}}));
		junitMenu.add(SwingUtil.menuItem("Run jUnit", new P0() {public void e() {
			Process junitProcess = ProcessUtil.exec("junit", appserverF.e() + "/scripts");
			ProcessUtil.showConsole("Run JUnit", junitProcess, frame);
		}}));
	}

	private static void dbItems(final AppFrame frame, JMenu dbMenu) {
		dbMenu.add(SwingUtil.menuItem("Keep count GB", ThreadUtil.async(new P0() {public void e() {
			try {
				Class.forName("oracle.jdbc.OracleDriver");
				final Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE","ergb","ergb");
				DatabaseMetaData metaData = conn.getMetaData();
				
				final List<String> tables = DbStatus.getStrings(metaData.getTables(conn.getCatalog(), "ER", "ER_%", new String[] {"TABLE"}),3);
				final Map<String, Integer> oldCounts = DbStatus.getCounts(tables,conn);
				
				JDialog dialog = SwingUtil.dialog("DB Count", frame);
				dialog.setModal(false);
				dialog.setPreferredSize(new Dimension(500, 200));
				dialog.add(SwingUtil.btn("Press this when finish unit test", new P0() {public void e() {
					Map<String, Integer> newCounts = DbStatus.getCounts(tables,conn);
					DesktopUI4.alert2("" + DbStatus.compare(newCounts, oldCounts));
				}}), BorderLayout.CENTER);
				
				SwingUtil.onClose(dialog, IOUtil.closeF(conn));
				
				SwingUtil.show(dialog);

			} catch (ClassNotFoundException e1) {
				throw new RuntimeException(e1);
			} catch (SQLException e1) {
				throw new RuntimeException(e1);
			}
			
		}})));
		dbMenu.add(SwingUtil.menuItem("Ant drop tables", new P0() {public void e() {
			String schema=DesktopUI4.prompt("Schema", "er");
			Process antProcess = ProcessUtil.exec("ant -Ddb.schema=" + schema + " drop", appserverF.e() + "/db/ant");
			ProcessUtil.showConsole("Ant drop", antProcess, frame);
		}}));
		dbMenu.add(SwingUtil.menuItem("Ant create tables", new P0() {public void e() {
			String schema=DesktopUI4.prompt("Schema", "er");
			Process antProcess = ProcessUtil.exec("ant -Ddb.schema=" + schema + " create", appserverF.e() + "/db/ant");
			ProcessUtil.showConsole("Ant create", antProcess, frame);
		}}));
	}

	private static void assemItems(final AppFrame frame, JMenu assemMenu) {
		assemMenu.add(SwingUtil.menuItem("Update Static All", new P0() {public void e() {
			Process vaProcess = ProcessUtil.exec("va usall", assemDirF.e());
			ProcessUtil.showConsole("VA Update Static All", vaProcess, frame);
		}}));
		assemMenu.add(SwingUtil.menuItem("Clear All", new P0() {public void e() {
			Process vaProcess = ProcessUtil.exec("va call", assemDirF.e());
			ProcessUtil.showConsole("VA Clear All", vaProcess, frame);
		}}));
		assemMenu.add(SwingUtil.menuItem("Build All", new P0() {public void e() {
			Process vaProcess = ProcessUtil.exec("va bpall", assemDirF.e());
			ProcessUtil.showConsole("VA Build All", vaProcess, frame);
		}}));
		assemMenu.add(SwingUtil.menuItem("Start work", new P0() {public void e() {
			String module = DesktopUI4.prompt2();
			
			if (StringUtil.isNotBlank(module)) {
				Process vaProcess = ProcessUtil.exec("va startwork " + module, assemDirF.e());
				ProcessUtil.showConsole("Start work " + module, vaProcess, frame);
			}
		}}));
		assemMenu.add(SwingUtil.menuItem("Open country.properties", new P0() {public void e() {
			DesktopUtil.openText(assemDirF.e() + "/country.properties");
		}}));
	}
	private static void fileItems(JMenu fileMenu, final AppFrame frame) {
		final AtomicReference<F2<String, P1<File>, P0>> searchF = new AtomicReference<F2<String,P1<File>,P0>>();
		onConfigUpdateds.add(new P0() {public void e() {
			searchF.set(null);
		}});
		fileMenu.add(SwingUtil.menuItem("Find files", new P0() {public void e() {
			if (searchF.get()==null) {
				searchF.set(FileUtil.searchF(projectHomeF.e()));
			}
			String fileName = DesktopUI4.prompt("File name");
			if (fileName==null) {
				return;
			}
			final F1<File, String> relPathF = FileUtil.getRelPath(new File(projectHomeF.e()));
			System.out.println("Search started...");
			searchF.get().e(fileName, new P1<File>() {public void e(File obj) {
				System.out.println(relPathF.e(obj));
			}});
			System.out.println("Search done.");
		}}));

		fileMenu.add(SwingUtil.menuItem("Search code in Java files", new P0() {public void e() {
			final String fileNameEndsWith = ".java";
			final String codeToFind = DesktopUI4.prompt("Code To Find");
			
			System.out.println("Search started...");
			FileUtil.eachFile(new File(projectHomeF.e()), new P2<File,String>() {public void e(File f, String path) {
				if (f.getName().endsWith(fileNameEndsWith)) {
					final boolean[] found = {false};
					StringUtil.eachLine(FileUtil.readFileToString(f), new F1<String,Boolean>() {public Boolean e(String line) {
						int indexOfCode = line.indexOf(codeToFind);
						if (indexOfCode > -1) {
							int indexOfComment = line.indexOf("//");
							if (indexOfComment==-1 || indexOfComment > indexOfCode) {
								found[0] = true;
								return true;
							}
						}
						return false;
					}});
					if (found[0]) {
						System.out.println(f.getPath());
					}
				}
			}});
			System.out.println("Search done.");
		}}));
		
		fileMenu.add(SwingUtil.menuItem("Search text in files", new P0() {public void e() {
			final String fileNameEndsWith = DesktopUI4.prompt("Ends with");
			final String stringToFind = DesktopUI4.prompt("Text To Find");
			
			System.out.println("Search started...");
			FileUtil.eachFile(new File(projectHomeF.e()), new P2<File,String>() {public void e(File f, String path) {
				if (f.getName().endsWith(fileNameEndsWith)) {
					if (FileUtil.readFileToString(f).contains(stringToFind)) {
						System.out.println(f.getAbsolutePath());
					}
				}
			}});
			System.out.println("Search done.");
		}}));
		fileMenu.add(SwingUtil.menuItem("Classpath", new P0() {public void e() {
			final StringBuilder sb = new StringBuilder("<!-- all libs start -->\n");
			P2<File,String> writePathF = new P2<File,String>() {public void e(File f, String path) {
				if (
						f.getName().equals("spring.jar") ||
						(f.getName().equals("ojdbc6.jar") && FileUtil.isChild(f, new File(projectHomeF.e()+ "/static"))) ||
						f.getName().equals("ojdbc14.jar")
						) {
					return;
				}
				
				if (f.getName().endsWith(".jar")) {
					sb.append("\t<classpathentry kind=\"lib\" path=\"" + f.getAbsolutePath() + "\"/>\n");
				}
			}};
			
			FileUtil.eachFile(new File(projectHomeF.e()+ "/static/BUILD/lib"), writePathF);
			FileUtil.eachFile(new File(projectHomeF.e()+ "/prepare/vjars"), writePathF);
			FileUtil.eachFile(new File(projectHomeF.e()+ "/prepare/lib"), writePathF);

			sb.append("<!-- all libs end -->\n");
			DesktopUI4.alert2(sb.toString());
		}}));

		fileMenu.add(SwingUtil.menuItem("Tail file dummy_if.log", new P0() {public void e() {
			
			final String path = dummyIfDirF.e()+"/log/dummy_if.log";
			
			showTail(path, frame);
			
		}}));
		fileMenu.add(SwingUtil.menuItem("Browse appserver", new P0() {public void e() {
			DesktopUtil.open(appserverF.e());
		}}));
	}
	
	private static void showTail(final String path, final AppFrame frame) {
		final JTextArea ta = new JTextArea(21, 80);
//		ta.setPreferredSize(new Dimension(400, 300));

		P0 stopF = FileUtil.onTextAdded(path, SwingUtil.writeF(ta));
		
		SwingUtil.console(ta);

		SwingUtil.onPopup(ta, new F1<Range, JPopupMenu>() {
			public JPopupMenu e(Range obj) {
				JPopupMenu menu = new JPopupMenu();
				menu.add(SwingUtil.menuItem("Clear", SwingUtil.async( new P0() {public void e() {
					ta.setText("");
				}})));
				menu.add(SwingUtil.menuItem("Open file", SwingUtil.async( new P0() {public void e() {
					DesktopUtil.openText(path);
				}})));
				return menu;
			}
		});
		
		final JDialog dialog = SwingUtil.dialog(ta, "Tail", frame);
		
		SwingUtil.onClose(dialog, stopF);
		
		show(dialog);
	}

	private static void useExampleZip(final AppFrame frame, String name) {
		File catalogExampleFile = new File(appserverF.e() + "/applications/ercore.ear/" + name + ".zip.example");
		File catalogFile = new File(appserverF.e() + "/applications/ercore.ear/" + name + ".zip");
		
		FileUtil.moveReplace(catalogExampleFile, catalogFile);
	}

	private static List<File> getLogFiles() {
		LinkedList<File> ret = new LinkedList<File>();
		for (File file : new File(appserverF.e() + "/logs").listFiles()) {
			if (file.isDirectory() || !file.getName().toLowerCase().endsWith(".log")) {
				continue;
			}
			ret.add(file);
		}
		return ret;
	}

	public static class Build {
		public static void main(String[] args) {
			BuildUtil.buildApp(AssemblerUI.class);
		}
	}
}
